<template>
  <div id="musicContainer" style="height: 800px">

  </div>
</template>

<script>
let echarts = require('echarts/lib/echarts')
require('echarts-gl')
export default {
  data () {
    return {
      msg: 'www'
    }
  },
  created () {
  },
  mounted () {
    this.musicChart = echarts.init(document.getElementById('musicContainer'))
    this.UPDATE_DURATION = 100
    window.AudioContext = window.AudioContext || window.webkitAudioContext
    this.audioContext = new AudioContext()
    this.oReq = new XMLHttpRequest()
    this.oReq.open('GET', 'http://p8o86ntcm.bkt.clouddn.com/BEYOND%20-%20%E6%97%A0%E6%82%94%E8%BF%99%E4%B8%80%E7%94%9F.mp3', true)
    this.oReq.responseType = 'arraybuffer'
    this.oReq.onload = (e) => {
      this.audioContext.decodeAudioData(this.oReq.response).then(this.initVisualizer)
    }
    this.oReq.send()
  },
  methods: {
    initVisualizer (audioBuffer) {
      // inited = true

      var source = this.audioContext.createBufferSource()
      source.buffer = audioBuffer

      // Must invoked right after click event
      if (source.noteOn) {
        source.noteOn(0)
      } else {
        source.start(0)
      }

      this.analyzer = this.audioContext.createAnalyser()
      this.gainNode = this.audioContext.createGain()
      this.analyzer.fftSize = 4096
      this.gainNode.gain.value = 1
      source.connect(this.gainNode)
      this.gainNode.connect(this.analyzer)
      this.analyzer.connect(this.audioContext.destination)
      this.frequencyBinCount = this.analyzer.frequencyBinCount
      this.dataArray = new Uint8Array(this.frequencyBinCount)
      this.beta = 0
      this.update()
    },
    update () {
      this.analyzer.getByteFrequencyData(this.dataArray)
      // var item = []
      var size = 50
      this.dataProvider = []
      for (var i = 0; i < size * size; i++) {
        var x = i % size
        var y = Math.floor(i / size)
        var dx = x - size / 2
        var dy = y - size / 2

        var angle = Math.atan2(dy, dx)
        if (angle < 0) {
          angle = Math.PI * 2 + angle
        }
        var dist = Math.sqrt(dx * dx + dy * dy)
        var idx = Math.min(
          this.frequencyBinCount - 1, Math.round(angle / Math.PI / 2 * 60 + dist * 60) + 100
        )

        var val = Math.pow(this.dataArray[idx] / 100, 3)
        this.dataProvider.push([x, y, Math.max(val, 0.1)])
      }
      var sOption = {
        tooltip: {},
        visualMap: {
          show: false,
          min: 0.1,
          max: 4,
          inRange: {
            color: ['#010103', '#2f490c', '#b0b70f', '#fdff44', '#3dff44', '#6dffaa']
          }
        },
        xAxis3D: {
          type: 'value'
        },
        yAxis3D: {
          type: 'value'
        },
        zAxis3D: {
          type: 'value',
          min: -6,
          max: 6
        },
        grid3D: {
          viewControl: {
            beta: this.beta,
            alpha: Math.sin(this.beta / 10 + 40) * (this.beta % 10 + 5) / 15 * 30 + 30,
            distance: Math.cos(this.beta / 50 + 20) * (this.beta % 10 + 5) / 15 * 50 + 80,
            animationDurationUpdate: this.UPDATE_DURATION,
            animationEasingUpdate: 'linear'
          },
          show: false,
          environment: '#000',
          postEffect: {
            enable: true,
            FXAA: {
              enable: true
            }
          },
          light: {
            main: {
              shadow: true,
              intensity: 10,
              quality: 'high'
            },
            ambientCubemap: {
              texture: 'data-gl/asset/canyon.hdr',
              exposure: 0,
              diffuseIntensity: 0.2
            }
          }
        },
        series: [{
          type: 'bar3D',
          silent: true,
          shading: 'lambert',
          barSize: 1,
          lineStyle: {
            width: 4
          },
          // animation: false,
          animationDurationUpdate: this.UPDATE_DURATION,
          data: this.dataProvider
        }]
      }
      this.musicChart.setOption(sOption)
      this.beta += 2
      setTimeout(this.update, this.UPDATE_DURATION)
    }
  }
}
</script>

<style lang="stylus">
  .musicContainer
      border 1px solid red
</style>
